/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2018-2021.
 * Description: support ubifs enhance feature
 * Author: yejianhua <yejianhua5@huawei.com>
 * Create: 2018-09-21
 */

#include <linux/random.h>
#include <linux/math64.h>
#include <linux/crc32.h>
#include "ubifs.h"
#include "force_recovery.h"

/**
 * skip the current node, and find the next node
 *
 * Return how many bytes are skipped if succeed, otherwise return a
 * negative value.
 */
int find_next_magic(const struct ubifs_info *c, char *buf, int len)
{
	struct ubifs_ch *ch = (struct ubifs_ch *) buf;
	int skip_len = 0, interval;

	/*
	 * Check if the first node has correct magic number. If it is, the
	 * node must be corrupted somewhere else. So skip the first 4
	 * bytes. If it is not, walk the buf and search the first magic
	 * number.
	 */
	interval = sizeof(ch->magic);

	if (le32_to_cpu(ch->magic) == UBIFS_NODE_MAGIC) {
		buf += interval;
		skip_len += interval;
		len -= interval;
	}

	while (len >= 8) {
		ch = (struct ubifs_ch *) buf;
		if (le32_to_cpu(ch->magic) == UBIFS_NODE_MAGIC)
			return skip_len;
		buf += interval;
		skip_len += interval;
		len -= interval;
	}

	return SCANNED_GARBAGE;
}

/**
 * Check how many bitflips occurs in empty space
 *
 * @buf: start address of empty space
 * @len: length of buf
 *
 * Return the number of bitflips in emtpy space
 */
unsigned int ubifs_count_bitflips(const struct ubifs_info *c, char *buf, int len)
{
	char *ptr = buf;
	unsigned int bitflips = 0;
	unsigned int i, j;

	for (i = 0; i < len; i++) {
		for (j = 0; j < 8; j++) {
			if (!((unsigned char)(*ptr) & (1 << j)))
				bitflips++;
		}
		ptr++;
	}
	return bitflips;
}
